package utils

import (
	"bufio"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"strings"
)


//获取指定目录下的所有文件，不进入下一级目录搜索，可以匹配后缀过滤。
func ListDir(dirPth string, suffix string) (files []map[string]interface{}, err error) {
	files = make([]map[string]interface{}, 0, 10000)

	dir, err := ioutil.ReadDir(dirPth)
	if err != nil {
		return nil, err
	}

	PthSep := string(os.PathSeparator)
	suffix = strings.ToUpper(suffix) //忽略后缀匹配的大小写

	for _, fi := range dir {
		maps := make(map[string]interface{})
		if fi.IsDir() { // 忽略目录
			maps["type"] = "dir"
		}else{
			maps["type"] = "file"
		}
		if strings.HasSuffix(strings.ToUpper(fi.Name()), suffix) { //匹配文件
			var pathName = ""
			maps["name"] = fi.Name()
			if dirPth[len(dirPth)-1:] == PthSep{
				pathName = dirPth+fi.Name()
			}else{
				pathName = dirPth+PthSep+fi.Name()
			}
			pathName = strings.Replace(pathName,PthSep+PthSep+PthSep+PthSep,PthSep+PthSep,-1)
			ext := path.Ext(pathName)
			maps["path"] = pathName
			maps["ext"] = ext
			maps["is_dir"] = fi.IsDir()
			maps["size"] = fi.Size()
			maps["mode"] = fi.Mode()
			maps["time"] = TimeFormat(fi.ModTime())
			maps["timestamp"] = fi.ModTime().Unix()
			files = append(files,maps )
		}
	}

	return files, nil
}

//获取指定目录及所有子目录下的所有文件，可以匹配后缀过滤。
func WalkDir(dirPth, suffix string) (files []string, err error) {
	files = make([]string, 0, 30)
	suffix = strings.ToUpper(suffix) //忽略后缀匹配的大小写

	err = filepath.Walk(dirPth, func(filename string, fi os.FileInfo, err error) error { //遍历目录
		//if err != nil { //忽略错误
		// return err
		//}

		if fi.IsDir() { // 忽略目录
			return nil
		}

		if strings.HasSuffix(strings.ToUpper(fi.Name()), suffix) {
			files = append(files, filename)
		}

		return nil
	})

	return files, err
}

func ReadFile(path string)(string,error){
	file, err := os.Open(path)
	if err != nil {
		return "",err
	}
	defer func(file *os.File) {
		err := file.Close()
		if err != nil {
			fmt.Printf("err=%v",err)
		}
	}(file)
	reader := bufio.NewReader(file)
	totalStr := ""
	for {
		str, err := reader.ReadString('\n')
		totalStr += str
		if err == io.EOF {
			break
		}
	}
	return totalStr,nil
}

func CreateDir(path string)error{
	err := os.Mkdir(path, os.ModePerm)
	return err
}

func CreateFile(path string)error{
	_, err := os.Create(path)
	return err
}

func WriteFile(path string,content string)error{
	err := ioutil.WriteFile(path, []byte(content), os.ModePerm)
	return err
}


func CopyFile(src, des string) (written int64, err error) {
	srcFile, err := os.Open(src)
	if err != nil {
		return 0, err
	}
	defer srcFile.Close()

	//获取源文件的权限
	fi, _ := srcFile.Stat()
	perm := fi.Mode()

	//desFile, err := os.Create(des)  //无法复制源文件的所有权限
	desFile, err := os.OpenFile(des, os.O_RDWR|os.O_CREATE|os.O_TRUNC, perm)  //复制源文件的所有权限
	if err != nil {
		return 0, err
	}
	defer desFile.Close()

	return io.Copy(desFile, srcFile)
}


func IsExistFile(filename string) bool {
	existed := true
	if _, err := os.Stat(filename); os.IsNotExist(err) {
		existed = false
	}
	return existed
}

func IsDir(name string) bool {
	if info, err := os.Stat(name); err == nil {
		return info.IsDir()
	}
	return false
}

func RemoveDirOrFile(filename string)error{
	if IsDir(filename){
		return RemoveDir(filename)
	}else{
		return RemoveFile(filename)
	}
}

func RemoveDir(dir string)error{
	err := os.RemoveAll(dir)
	return err
}

func RemoveFile(filename string)error{
	err := os.Remove(filename)
	return err
}

func RenameFile(path string, old string, new string) (err error) {
	var pathSeparator = string(os.PathSeparator)
	var pathName string
	if path[len(path)-1:] == pathSeparator{
		pathName = path
	}else{
		pathName = path + pathSeparator
	}
	err = os.Rename(pathName+old,pathName+new)
	return err
}
